iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
自我挑戰組

從零開始的AI學習之路:非本科轉職的30天挑戰記系列 第 15

D15 | Side Project 每拍呷 之 蒐集資料篇

  • 分享至 

  • xImage
  •  

繼續做我的AI Side Project:「每拍呷-營養標示一拍就懂」/images/emoticon/emoticon07.gif

✔️今日進度1/14:確認營養標示算法、蒐集資料、統整國民健康署DIRS、把熱量&鈉&糖&脂肪換算成白飯&醬油&方糖&沙拉油、暫時先用GRADIO介面做初步的測試。

先看了家裡的零食,確認營養標示算法,我決定要先直接算吃完一整包的量,以後如果行有餘力,可以讓用戶選擇份量,譬如說吃了一包、半包、1/4包,或是秤克數。

各種算數學:

  • 每日鈉總攝取量不宜超過2400毫克(即6公克鹽=1茶匙鹽=2又2/5湯匙醬油)(1茶匙=5cc;1湯匙=15cc)
    (算到這裡覺得好驚人喔!原來一天吃超過一茶匙鹽就爆表了,那很多人應該也是每天爆表)

  • 添加糖攝取量不宜超過總熱量的10%(1顆方糖5公克),以總熱量1200大卡為例,10%則為120大卡,因為1克糖是產生4大卡熱量,故建議糖攝取量為30g,不能超過6顆方糖。
    依據食藥署食品營養成分資料庫,1杯700毫升的「全糖」珍珠奶茶,含糖量近62公克,一天一杯就超過每日糖攝取上限。

  • 脂肪每日建議攝取量上限是男性70公克與女性55公克、飽和脂肪每日建議攝取量上限是男性23公克、女性18公克(男、女性分別以體重70、55公斤之靜態工作者估計),我先暫時算總脂肪就好。1份油脂=15粒開心果=1茶匙沙拉油5克。後續測試先參考女性靜態工作者的55克,之後會考慮將用戶的性別加入設定。

  • 簡易食物代換:
    一份主食=1/2碗熟麵條=1片吐司=白飯1/4碗(約40克70大卡);
    一平碗的白飯約有160公克、熱量280大卡。
    我覺得代換成白飯應該比麵條跟吐司更直覺,所以就決定是白飯了!
    然後統一規格,數字都一律四捨五入到小數點後一位;
    之後我還要放警語,類似「本分析結果僅供參考、如有醫療相關問題請諮詢醫院」之類的

import math
import gradio as gr 

# --- 營養素常數與換算表 ---
NUTRITION_CONSTANTS = {
    # 每日建議攝取量 (DRIs)
    "DRIS": {
        # 鈉:單位毫克(mg),以衛福部建議的2400mg為準
        "SODIUM_UPPER_LIMIT_MG": 2400,
        # 糖:單位公克(g),以1200大卡總熱量為例,10%熱量相當於30g糖
        "SUGAR_UPPER_LIMIT_G": 30,
        # 脂肪:單位公克(g),參考女性靜態工作者的55公克
        "FAT_FEMALE_UPPER_LIMIT_G": 55,
    },
    # 食物代換與比喻
    "CONVERSIONS": {
        # 白飯:1平碗約160克,280大卡
        "RICE_KCAL_PER_BOWL": 280,
        # 鹽與醬油:2400mg鈉(6g鹽) = 2.4湯匙醬油,得出1湯匙醬油約含1000mg鈉
        "SODIUM_MG_PER_TBS_SOY_SAUCE": 1000,
        # 脂肪與沙拉油:1茶匙沙拉油5克脂肪
        "FAT_G_PER_TSP_OIL": 5,
        # 糖與方糖:1顆方糖5公克
        "SUGAR_G_PER_CUBE": 5,
    }
}

def analyze_and_report_nutrition(
    serving_size_g_str: str, # 接收字串類型
    servings_per_package_str: str, # 接收字串類型
    sodium_per_serving_mg_str: str, # 接收字串類型
    sugar_per_serving_g_str: str, # 接收字串類型
    fat_per_serving_g_str: str, # 接收字串類型
    calories_per_serving_kcal_str: str # 接收字串類型
) -> str:
    """
    根據單份營養標示和總份數,計算並生成完整的營養報告,並使用表情符號。

    Args:
        serving_size_g_str: 每一份的克數 (字串)。
        servings_per_package_str: 本包裝含幾份 (字串)。
        sodium_per_serving_mg_str: 每一份含的鈉(毫克,字串)。
        sugar_per_serving_g_str: 每一份含的糖(公克,字串)。
        fat_per_serving_g_str: 每一份含的脂肪(公克,字串)。
        calories_per_serving_kcal_str: 每一份含的熱量(大卡,字串)。

    Returns:
        一個包含所有計算結果和建議的文字回覆。
    """
    try:
        # 將字串輸入轉換為浮點數
        serving_size_g = float(serving_size_g_str)
        servings_per_package = float(servings_per_package_str)
        sodium_per_serving_mg = float(sodium_per_serving_mg_str)
        sugar_per_serving_g = float(sugar_per_serving_g_str)
        fat_per_serving_g = float(fat_per_serving_g_str)
        calories_per_serving_kcal = float(calories_per_serving_kcal_str)
    except ValueError:
        return "### 輸入錯誤:請確認您輸入的都是有效的數字喔!" # 錯誤訊息也放大字體
    except Exception as e:
        return f"### 發生未知錯誤:{e}" # 錯誤訊息也放大字體

然後是計算是否有超過一天攝取量限制的部份,分成鈉、糖、脂肪三項,如果超過100%就回覆攝取已爆表:

# 加入警示判斷
    warnings = []
    if sodium_percentage > 100:
        warnings.append("⚠️ **注意:鈉攝取已爆表!**")
    if sugar_percentage > 100:
        warnings.append("⚠️ **注意:糖攝取已爆表!**")
    if fat_percentage > 100:
        warnings.append("⚠️ **注意:脂肪攝取已爆表!**")
    
    if warnings:
        message_parts.append("\n" + "\n".join(warnings))
    

emoji的部份也很重要!讓LINE的對話框訊息變活潑!

綜合評分部份

用emoji加紅綠燈來表示,預設為😊笑臉。
如果任一營養素超過100%,則會變成😡生氣臉。
如果沒有生氣臉的情況,但有任一營養素介於**75%到100%**之間,則會變成😟哭臉。

具體警示符號:

營養素超過100%的警示使用⚠️。
介於75%到100%的提醒,使用對應的食物符號(鈉🧂-->鹽罐,糖🍬-->糖果,脂肪🧈-->奶油塊)。

https://ithelp.ithome.com.tw/upload/images/20250820/201779749E0liVOJYK.png
https://ithelp.ithome.com.tw/upload/images/20250820/20177974ejTM9bnYec.png

明日進度:
因為今天提前做了明天原本要做的紅綠燈分類,明天改成針對成分表裡的食品添加物作分類,初步分類成:香料、防腐劑、乳化劑、色素、其他,用戶輸入文字內容後,可收到圓餅圖或其他視覺化分析內容。

加油!!


上一篇
D14 | 終於要開始做我的AI Side Project--每拍呷
下一篇
D16 | 我的Side Project每拍呷--視覺化資訊篇
系列文
從零開始的AI學習之路:非本科轉職的30天挑戰記30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言